#ifndef GAMEENGINE_H
#define GAMEENGINE_H

#include <SDL/SDL.h>
#include <vector>
#include "../graphicElement/graphicElement.h"
#include "../tool/PointOfView.h"
#include "../actions/action.h"
#include "../CollisionDetection/collision.h"

/*!
 * 	\class GameEngine
 * 	\brief Classe dérivable utilisé pour représenter les actions orchestré par un jeu vidéo à chaque rafraichissement de l'image
 */
 
#include "openglsystem.h"
#include "sdlwindow.h"

class GameEngine
{
    public :
	
    GameEngine();

    std::vector<AbstractDelegate *> delegates;      /*!<    Evénements lié au jeu ou à la fenêtre   */
    std::vector<AbstractCollision * > collisions;   /*!<   Détection de collisions entre surfaces englobantes   */
    std::vector<GraphicElement *> elements;    /*!<    Liste des éléments affichable de la scène */
    std::vector<AbstractSlot *> * mesActions;
    std::vector<Action * > actions;

    Uint8 * keyboardState;  /*!< Variable utilisé pour "mapper" le statut des touches du clavier */

    int frameCount;     /*!< Nombre de rafraichissement de l'image éffectué depuis le début */
    int currentTime;    /*!< Valeur temporelle actuelle */
    int lastTime;       /*!< Valeur temporelle du dernier rafraichissement de l'image	*/
    int dimension;                  /*!<    Détermine si l'application est en 2D ou 3D  */

    int frameRate;      /*!< Nombre d'image par seconde souhaité */

    openGLSystem * openglSystem ;   /*!< Représente les bornes supérieurs et inférieur de l'espace Opengl */
    SDLWindow * window;             /*!< Représente la fenêtre utilisé pour afficher le contenu OpenGL */
    PointOfView pow;                /*!< Représente une caméra dans l'espace 3D */

    SDL_Event event;                /*!<    Objet récupérant l'événement en cours renvoyer par la méthode SDL_PollEvent */


    /*!
     *  \fn void InitSDL(int width, int height);
     *  \brief  Initialise la fenêtre de jeu, crée à l'aide de la librairie SDL
     */

    virtual void InitSDL(int width, int height);

    /*!
     *  \fn void InitGL();
     *  \brief  Initialise le contexte/variables/constantes nécéssaire à l'affichage d'un rendu OpenGL
     */

    virtual void InitGL();

    /*!
     *  \fn void InitOrthoProjection()
     *  \brief  Initialise la matrice de projection de manière "ortho"
     */

    virtual void InitOrthoProjection(float aLowerBoundx, float aUpperBoundx, float aLowerBoundy, float aUpperBoundy );

    /*!
     *  \fn InitFrustsumProjection
     *  \brief  Initialise la matrice de projection en perspective
     */

    virtual void InitFrustsumProjection();

    /*!
     *  \fn void EventManagement()
     *  \brief  Inspecte tous les délégués des éléments stocker dans le conteneur element afin de lancer ou non leurs
     *          slots correspondant
     */

    virtual void EventManagement();
    virtual void InputEventManagement();


    /*!
     *  \fn void DisplayFrame();
     *  \brief  Exécute la méthode Display de tous les éléments du conteneur std::vector<Displayable *> elements
     */

    virtual void DisplayFrame();

    /*!
     *  \fn void GameLoop()
     *  \brief  Exécute toutes les méthodes nécéssaire à un tour de boucle dans un jeu
     */

    virtual void GameLoop();

    void DefineCamera();

    void AddElement(GraphicElement *);
    void AddElements(std::vector<GraphicElement *> elements);

    void DisplayPicking(void);
    void CalculPosition();
    void SetGravity();
    void CheckCollision();
    void DoAction();

    void InitShaders();

    /*!
     *  \fn int ReadShaders(std::string fileName, GLint idShader)
     *  \brief  Charge le contenu d'un fichier de code shader à l'intérieur d'un shaders
     */

    int ReadShaders(std::string fileName, GLint idShader);

    void InitLighting();


};
#endif
